/**
 * 存储购物车商品列表数据
 */

import { mergeLocalCartApi, findCartListApi, insertCartApi, deleteCartApi, updateCartApi, checkAllCartApi } from '@/api/cart'

export default {
  namespaced: true, // 模块枷锁
  // 1. 定义变量
  state: {
    list: [] // 购物车列表数据
  },

  getters: {
    /**
     * 对购物车商品列表 list 做计算:
     * 1. 有效商品列表 -> 无效商品(没库存或下架了)
     * 2. 选中的购物车商品列表
     * 3. 选中商品总价
     * 4. 购物车中有效商品是否是全部选中状态
     */
    // 有效商品列表
    validList: state => {
      // 根据 item.isEffective 值: true 留下 | false 去掉
      return state.list.filter(item => item.isEffective)
    },

    // 有效商品==选中的商品列表
    /**
     * @param {*} state 所有 state 变量
     * @param {*} getters getters 计算属性所有变量
     */
    validSeledList (state, getters) {
      return getters.validList.filter(item => item.selected)
    },

    // 有效商品==选中的商品列表==所有商品总价
    /**
     * 单个商品价格计算: 商品的现价 nowPrice * 商品的数量 count
     * == 有效的选中的商品的总价(validSeledList): 每个商品价格之和 ==
     * @param {*} state
     * @param {*} getters
     * @returns
     */
    validSeledListTotal (state, getters) {
      // 写法1: forEach 实现
      // 总价
      // let total = 0
      // getters.validSeledList.forEach(item => {
      //   // 累加
      //   total += item.nowPrice * item.count
      // })
      // return total
      // 写法2: reduce 实现
      return getters.validSeledList.reduce((total, item) => total + item.nowPrice * item.count, 0)
    },

    // 有效商品是否是全部选中状态: true 全部选中 | false 未全部选中(至少有一个没有选中)
    validListSeledAll (state, getters) {
      /**
       * 1. every 方法: 所有都满足才返回 true
       * 2. some 方法: 只要有一个满足就返回 true
       */
      return getters.validList.every(item => item.selected)
    }
  },
  // state: () => ({
  //   return {
  //     list: []
  //   }
  // }),

  // 2. 修改变量(同步)
  mutations: {
    setList (state, list) {
      state.list = list
    },

    /**
     * 加入购物车
     * @param {*} state
     * @param {*} skuGood
     */
    addCart (state, skuGood) {
      /**
       * 判断之前是否加入过该商品? (排重)
       * 1. 加入过: 数量的增加
       * 2. 没有加入过: 新增
       */
      /**
       * state.list 获取已经加入购物车商品
       *
       * state.list.findIndex 方法判断当前 skuGood 商品是否在 list 中:
       * 1. 存在: 返回存在 sku 商品的索引值
       * 2. 不存在: 返回 -1
       */
      const index = state.list.findIndex((item) => item.skuId === skuGood.skuId)
      if (index === -1) {
        // 不存在 -> 添加到数组的第一个位置
        state.list.unshift(skuGood)
      } else {
        // 存在 -> state.list[index] 获取当前已经存在的商品, 进行数量增加
        state.list[index].count += skuGood.count
      }
    },

    /**
     * @param {*} state state
     * @param {*} param1 { good:当前勾选的商品, sel:当前商品的勾选状态 }
     */
    singleSel (state, { good, sel }) {
      /**
       * 1. 在 state.list 中找到要修改的商品
       * 2. 修改商品的选中
       */
      const currGood = state.list.find((item) => item.skuId === good.skuId)
      currGood.selected = sel
    },

    /**
     * @param {*} state
     * @param {*} isSelAll 全选框选中的 boolean 值
     */
    selAll (state, isSelAll) {
      /**
       * 全选和取消全选:
       * 如果全选框:
       * 1. 选中 true: 列表全部选中
       * 2. 未选中 false: 列表全部取消选中
       */
      state.list.forEach(item => {
        // 每个商品的选中和全选框选中的值一样的
        item.selected = isSelAll
      })
    },

    /**
     * 数量修改
     * @param {*} state
     * @param {*} param1
     */
    changeNum (state, { good, num }) {
      const currGood = state.list.find((item) => item.skuId === good.skuId)
      currGood.count = num
    },

    /**
     * @param {*} state
     * @param {*} good 删除要删除的商品
     */
    delCart (state, good) {
      // filter: 排除 good 商品
      state.list = state.list.filter(item => item.skuId !== good.skuId)
    }

  },

  // 3. 发送请求(异步)
  actions: {
    async mergeCartAction ({ state, dispatch }) {
      /**
       * 需求: 把之前未登录的时候, 存到本地购物车商品列表, 合并到当前登录人名下, 存到数据库
       * 流程:
       * 1. 获取本地购物车商品列表数据, dispatch-> ctx.state
       * 2. 判断未登录的时候, 本地有没有存储购物车数据
       *    有存储 -> 调用后台接口, 执行合并
       * 3. 调用接口查询购物车最新的数据存到 vuex -> 渲染显示
       */
      if (state.list.length > 0) {
        // 本地有存储购物车数据 -> 调用后台接口, 执行合并
        // 1. 获取后台需要的待合并的购物车列表数据
        const mergeData = state.list.map((item) => {
          return {
            skuId: item.skuId,
            selected: item.selected,
            count: item.count
          }
        })
        console.log('后台需要的待合并的购物车列表数据: ', mergeData)
        await mergeLocalCartApi(mergeData)
      }
      // 调用接口查询==登录人==购物车最新的数据存到 vuex -> 渲染显示
      dispatch('getCartListAction')
    },

    /**
     * 从数据库查询 -> 当前登录人的 -> 最新的购物车列表数据
     * @param {*} param0
     */
    async getCartListAction ({ commit }) {
      const { data } = await findCartListApi()
      console.log('登录人的购物车列表: ', data)
      commit('setList', data)
    },

    /**
     * @param {*} param0
     * @param {*} skuGood 当前加入购物车的 sku 组合商品
     * @return Promise对象
     *
     * 购物车逻辑:
     * 问题? 怎么判断是否登录
     * 1. 未登录
     *  数据存到 vuex (不需要调用后台接口)
     *
     * 2. 已经登录
     *  数据存到数据库 (需要调用后台接口)
     */
    async addCartAction ({ commit, rootState, dispatch }, skuGood) {
      // 判断是否是登录 -> 根据是否有 token
      // console.log('action上下文ctx: ', ctx)
      if (rootState.user.profile.token) {
        // 已经登录
        // console.log('已登录')
        // 1. 调用加入购物车的接口
        await insertCartApi(skuGood)
        // 2. 从数据库查询最新的购物车数据
        dispatch('getCartListAction')
      } else {
        // 未登录
        // console.log('未登录-新增的sku商品信息: ', skuGood)
        // 调用 mucations 方法加入购物车
        commit('addCart', skuGood)
      }
      return '加入购物车成功'
    },

    /**
     * 商品单选
     * @param {*} param0
     * @param {*} skuGood
     * @returns
     */
    async singleSelAction ({ commit, rootState, dispatch }, { good, sel }) {
      if (rootState.user.profile.token) {
        // 已经登录
        // console.log('已登录')
        await updateCartApi({ ...good, selected: sel })
        dispatch('getCartListAction')
      } else {
        // 未登录
        commit('singleSel', { good, sel })
      }
    },

    // 全选
    async selAllAction ({ commit, rootState, dispatch, getters }, isSelAll) {
      if (rootState.user.profile.token) {
        // 已经登录
        // console.log('已登录')
        const ids = getters.validList.map(item => item.skuId)
        await checkAllCartApi({ selected: isSelAll, ids })
        dispatch('getCartListAction')
      } else {
        // 未登录
        commit('selAll', isSelAll)
      }
    },

    /**
     * @param {*} param0
     * @param {*} good 修改数量的商品  num 修改的数量
     */
    async changeNumAction ({ commit, rootState, state, dispatch }, { good, num }) {
      if (rootState.user.profile.token) {
        // 已经登录
        console.log('已登录')
        await updateCartApi({ ...good, count: num })
        dispatch('getCartListAction')
      } else {
        // 未登录
        console.log('当前模块数据：', state)
        commit('changeNum', { good, num })
      }
    },

    /**
     * @param {*} param0
     * @param {*} good 当前删除商品
     */
    async delCartAction ({ commit, rootState, dispatch }, good) {
      if (rootState.user.profile.token) {
        // 已经登录
        // console.log('已登录')
        await deleteCartApi([good.skuId])
        dispatch('getCartListAction')
      } else {
        // 未登录
        commit('delCart', good)
      }
    }

  }
}
